﻿using OperationPlugins.Mvc.Filters;
using System.Web.Mvc;
using System.Web.Security;
using TimeProject.Engine;
using TimeProject.Engine.DbContent;
using TimeProject.Engine.DbModels;
using TimeProject.Engine.Security;
using TimeProject.WebSite.ViewModels;
using WebMatrix.WebData;

namespace TimeProject.WebSite.Controllers
{
    public partial class TimeProjectController
    {
        [HttpGet]
        [CurrentOperation(TimeProjectOperations.Register)]
        [AllowAnonymous]
        public ActionResult Register()
        {
            RegisterViewModel vm = new RegisterViewModel();
            return View(vm);
        }

        [HttpPost]
        [CurrentOperation(TimeProjectOperations.Register)]
        [AllowAnonymous]
        public ActionResult Register(RegisterViewModel vm)
        {
            return Json(vm, () =>
            {
                try
                {
                    Db.GetTimestampData = () => new TimeProjectDbContext.TimestampData
                           {
                               RequestUsername = vm.Username,
                               RequestTimestamp = RequestContext.Current.RequestTimestamp
                           };

                    // Create user and account.
                    WebSecurity.CreateUserAndAccount(
                        vm.Username,
                        vm.Password,
                        new
                        {
                            FullName = vm.FullName,
                            EMail = vm.EMail,
                            IsActive = true,
                            Creator = vm.Username,
                            Created = RequestContext.Current.RequestTimestamp
                        });

                    // Set user as contributor.
                    Roles.AddUserToRole(vm.Username, UserRoles.GetRoleId(UserRole.Contributor));

                    // The basic data of the new user.
                    User user = Db.GetUser(vm.Username);

                    // Create a default organization for the user.
                    Organization organization = new Organization();
                    organization.Code = "PRIVATE";
                    organization.FullName = "My private organization";
                    organization.Description = "This is my system generated organization.";
                    Db.Organizations.Add(organization);

                    OrganizationUser organizationUser = new OrganizationUser();
                    organizationUser.UserId = user.Id;
                    organization.IdAssigned += (sender, e) => organizationUser.OrganizationId = e.Id;
                    organizationUser.Role = OrganizationUserRole.Manager;
                    organizationUser.Status = OrganizationUserStatus.Valid;
                    Db.OrganizationUsers.Add(organizationUser);

                    // Login.
                    WebSecurity.Login(vm.Username, vm.Password);
                    Db.UserActivities.Add(new UserActivity { UserId = user.Id, Type = UserActivityType.Login });

                    if (SaveDbContext() == false)
                    {
                        WebSecurity.Logout();
                    }
                    else
                    {
                        vm.RedirectTo("Index");                        
                    }
                }
                catch (MembershipCreateUserException ex)
                {
                    string s;

                    // See http://go.microsoft.com/fwlink/?LinkID=177550 for a full list of status codes.
                    switch (ex.StatusCode)
                    {
                        case MembershipCreateStatus.DuplicateUserName:
                            s = "Username already exists. Please enter a different username.";
                            break;
                        case MembershipCreateStatus.DuplicateEmail:
                            s =
                                "A username for that e-mail address already exists. Please enter a different e-mail address.";
                            break;
                        case MembershipCreateStatus.InvalidPassword:
                            s = "The password provided is invalid. Please enter a valid password value.";
                            break;
                        case MembershipCreateStatus.InvalidEmail:
                            s = "The e-mail address provided is invalid. Please check the value and try again.";
                            break;
                        case MembershipCreateStatus.InvalidAnswer:
                            s =
                                "The password retrieval answer provided is invalid. Please check the value and try again.";
                            break;
                        case MembershipCreateStatus.InvalidQuestion:
                            s =
                                "The password retrieval question provided is invalid. Please check the value and try again.";
                            break;
                        case MembershipCreateStatus.InvalidUserName:
                            s = "The username provided is invalid. Please check the value and try again.";
                            break;
                        case MembershipCreateStatus.ProviderError:
                            s =
                                "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
                            break;
                        case MembershipCreateStatus.UserRejected:
                            s =
                                "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
                            break;
                        default:
                            s =
                                "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
                            break;
                    }

                    vm.Messages.AddErrorMessage(s);
                }
            });
        }

    }
}